<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>流向分析</title>
    <script src="/js/ll.js"></script>
    <link href="/css/font.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3b82f6',
                        secondary: '#64748b',
                        accent: '#0ea5e9',
                        neutral: '#f1f5f9',
                        'neutral-dark': '#334155',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .table-shadow {
                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            }
            .table-fixed-layout {
                table-layout: fixed;
                width: 100%;
            }
            .table-fixed-layout th,
            .table-fixed-layout td {
                border: 1px solid #ddd;
                padding: 8px;
                white-space: nowrap;
            }

            .hover-scale {
                transition: all 0.2s ease-in-out;
            }
            .hover-scale:hover {
                box-shadow: 0 6px 25px rgba(0, 0, 0, 0.12);
            }
            .sortable-header {
                cursor: pointer;
                user-select: none;
                transition: all 0.2s ease;
            }
            .sortable-header:hover {
                background-color: #f3f4f6;
                transform: none;
            }
            .sort-icon {
                margin-left: 4px;
                opacity: 0.5;
            }
            .sort-icon.active {
                opacity: 1;
                color: #3b82f6;
            }
            .sticky-header {
                position: sticky;
                top: 0;
                z-index: 50;
            }
            .sticky-search {
                position: sticky;
                top: 60px;
                z-index: 40;
                background: white;
                padding-top: 16px;
            }
            .sticky-table-header {
                position: sticky;
                top: 240px;
                z-index: 30;
            }

            .sticky-table-header th {
                background: #f9fafb;
            }

            .sticky-container {
                position: sticky;
                top: 0;
                z-index: 50;
                background-color: #f9fafb;
            }

            .sticky-content {
                position: sticky;
                top: 60px;
                z-index: 49;
            }

            .overflow-x-auto {
                position: relative;
                z-index: 10;
                margin-top: -24px;
                padding-top: 24px;
            }

            .compact-btn {
                @apply px-3 py-2 rounded-md transition-colors text-sm flex items-center;
            }

            .table-stats {
                @apply bg-gray-50 px-4 py-2 text-sm text-gray-600 border border-t-0 border-gray-200 rounded-b-lg;
            }

            .update-time {
                @apply text-lg text-gray-500 italic;
            }

            .filter-container {
                @apply bg-white rounded-lg shadow-md p-4 mb-4;
            }
            .filter-item {
                @apply flex justify-between items-center p-2 border-b border-gray-100 hover:bg-gray-50 rounded;
            }
            .filter-actions {
                @apply flex space-x-2;
            }
            .filter-management-btn {
                @apply px-2 py-1 text-xs rounded hover:bg-gray-100 transition-colors;
            }
            .active-filter-tag {
                @apply inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800 mr-2 mb-2;
            }
            .active-filter-remove {
                @apply ml-1 h-4 w-4 flex items-center justify-center rounded-full bg-blue-200 text-blue-700 hover:bg-blue-300 cursor-pointer;
            }

            /* 新增：紧凑的过滤选项样式 */
            .compact-filter {
                padding: 2px 8px !important;
                font-size: 12px !important;
            }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans">
<div class="sticky-container">
    <!-- 导航头部 - 滚动置顶 -->
    <header class="bg-white shadow-sm sticky-header">
        <div class="flex justify-between items-center px-4 py-1">
            <!-- 左侧标题区域 -->
            <div class="flex items-center w-full justify-start px-0 py-0 space-x-4">
                <i class="fa fa-line-chart text-primary text-2xl"></i>
                <h1 class="text-xl font-bold text-primary">概念资金流向分析</h1>
                <div class="text-lg ml-4"  style="color: red">
                    最后更新: <span id="lastUpdateTime">-</span>
                </div>
                <h2 class="text-xl md:text-2xl font-bold" style="color: red">{大盘->板块->个股||主力->热度->分时}概念:前50,个股:前500</h2>

                <ul class="flex space-x-4 sm:space-x-6">
                    <li><a href="/" class="text-primary font-medium hover:text-primary/80 transition-colors">首页</a></li>
                    <li><a href="/analysis" class="text-gray-600 hover:text-primary transition-colors">数据分析</a></li>
                    <li><a href="/limitup/search" class="text-gray-600 hover:text-primary transition-colors">ZT分析</a></li>
                    <li><a href="/stocksflow" class="text-gray-600 hover:text-primary transition-colors">个股资金</a></li>
                </ul>

            </div>
        </div>

        <div class="flex justify-between items-center px-4 py-1">

            <!-- 右侧按钮和导航链接区域 -->
            <div class="flex flex-wrap items-center gap-2 filter-button-group">
                <button id="delSelectStock" class="text-white compact-btn bg-green-600 hover:bg-green-700" onclick="removeupdateFocusGainian()">
                    <span>取消关注</span>
                </button>
                <button id="addSelectStock" class="text-white compact-btn bg-secondary hover:bg-secondary/90" onclick="addupdateFocusGainian()">
                    <span>关注选择</span>
                </button>
                <button id="SelectStock" class="text-white compact-btn bg-green-600 hover:bg-green-700" onclick="getSelectedStockCodesJQ()">
                    <span>复制选择</span>
                </button>
                <button id="SelectStockSearch" class="text-white compact-btn bg-secondary hover:bg-secondary/90" onclick="jumpToEastMoneySearch()">
                    <span>查询资讯</span>
                </button>
                <div class="flex items-end">
                    <button id="searchBtn" class="bg-primary hover:bg-primary/90 text-white px-6 py-2 rounded-lg transition-all duration-300 flex items-center">
                        <i class="fa fa-search mr-2"></i>查询/刷新
                    </button>
                </div>
                <div class="flex-1 min-w-[80px]">
                    <div class="flex gap-1">
                        <input type="date" id="startDate" class="flex-1 px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary">
                    </div>
                </div>

                <button id="getGainian" class="text-white compact-btn bg-green-600 hover:bg-green-700" onclick="openSelectedGainianCodesJQ()">
                    <span>查看选择</span>
                </button>
                <button id="resetFilters" class="text-white compact-btn bg-gray-600 hover:bg-gray-700" onclick="resetAllFilters()">
                    <i class="fa fa-refresh mr-1"></i>重置
                </button>
                <button id="saveFilterBtn" class="text-white compact-btn bg-purple-600 hover:bg-purple-700" onclick="showSaveFilterDialog()">
                    <i class="fa fa-save mr-1"></i>保存条件
                </button>

                <div class="relative">
                    <select id="loadFilterSelect" class="pl-4 pr-8 py-3 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-indigo-600 text-white hover:bg-indigo-700 compact-btn">
                        <option value="">加载条件 ▼</option>
                    </select>
                    <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-white">
                        <i class="fa fa-chevron-down text-xs"></i>
                    </span>
                </div>

                <button id="deleteSelectedFilterBtn" class="px-2 py-2 text-gray-500 hover:text-red-600 transition-colors " onclick="deleteSelectedFilter()">
                    <i class="fa fa-trash"></i>
                </button>

                <button class="text-white compact-btn bg-purple-600 hover:bg-purple-700" onclick="openIwencaizhishu()">
                    指数热榜
                </button>
            </div>

        </div>

        <!-- 过滤条件保存对话框 -->
        <div id="saveFilterDialog" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
            <div class="bg-white rounded-lg p-6 w-full max-w-md">
                <h3 class="text-xl font-bold mb-4">保存过滤条件</h3>
                <div class="mb-4">
                    <label for="filterName" class="block text-sm font-medium text-gray-700 mb-1">条件名称</label>
                    <input type="text" id="filterName" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入条件名称">
                </div>
                <div class="mb-4">
                    <label for="filterDescription" class="block text-sm font-medium text-gray-700 mb-1">条件描述（可选）</label>
                    <textarea id="filterDescription" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入条件描述"></textarea>
                </div>
                <div class="flex justify-end space-x-3">
                    <button onclick="hideSaveFilterDialog()" class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">取消</button>
                    <button onclick="saveCurrentFilter()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90">保存</button>
                </div>
            </div>
        </div>

        <!-- 已保存的过滤条件列表 -->
        <div id="savedFiltersContainer" class="hidden filter-container">
            <h3 class="font-medium text-lg mb-3">已保存的过滤条件</h3>
            <div id="savedFiltersList" class="max-h-40 overflow-y-auto">
                <div class="text-center text-gray-500 py-4">暂无保存的过滤条件</div>
            </div>
        </div>

        <div class="flex justify-between items-center px-4 py-1">
            <!-- 搜索区域与按钮整合 - 过滤项已缩短 -->
            <div class="flex-1 flex flex-col md:flex-row gap-4 items-start md:items-center w-full flex-wrap">
                <!-- 名称模糊查询 -->
                <div class="flex-1 min-w-[240px]">
                    <div class="relative">
                        <span class="absolute inset-y-0 left-0 flex items-center pl-3">
                            <i class="fa fa-search text-gray-400"></i>
                        </span>
                        <input type="text"  id="nameSearch"  placeholder="输入概念名称关键词搜索...=关注" class="block w-full pl-10 pr-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary">
                    </div>
                </div>

                <!-- 涨幅过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="changePercentFilter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">所有涨幅</option>
                            <option value="0.01-2">0-2%</option>
                            <option value="2-5">2-5%</option>
                            <option value="5-7">5-7%</option>
                            <option value="7-10">7-10%</option>
                            <option value="10+">10%+</option>
                            <option value="-2-0">-2-0%</option>
                            <option value="-5-2">-5--2%</option>
                            <option value="-7-5">-7--5%</option>
                            <option value="-10-7">-10--7%</option>
                            <option value="-10-">＜-10%</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 1天资金过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="day1Filter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">1天资金</option>
                            <option value="0.01-50">0-50亿</option>
                            <option value="50-100">50-100亿</option>
                            <option value="100-500">100-500亿</option>
                            <option value="500+">500亿+</option>
                            <option value="-50-0">-50-0亿</option>
                            <option value="-100-50">-100--50亿</option>
                            <option value="-500-100">-500--100亿</option>
                            <option value="-500-">＜-500亿</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 10天资金过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[100px]">
                    <div class="relative">
                        <select id="day10Filter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">10天资金</option>
                            <option value="0.01-200">0-200亿</option>
                            <option value="200-500">200-500亿</option>
                            <option value="500-1000">500-1000亿</option>
                            <option value="1000+">1000亿+</option>
                            <option value="-100-0">-100-0亿</option>
                            <option value="-500-100">-500--100亿</option>
                            <option value="-1000-500">-1000--500亿</option>
                            <option value="-1000-">＜-1000亿</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 20天资金过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[100px]">
                    <div class="relative">
                        <select id="day20Filter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">20天资金</option>
                            <option value="0.01-200">0-200亿</option>
                            <option value="200-500">200-500亿</option>
                            <option value="500-1000">500-1000亿</option>
                            <option value="1000-5000">1000-5000亿</option>
                            <option value="5000+">5000亿+</option>
                            <option value="-500-0">-500-0亿</option>
                            <option value="-1000-500">-1000--500亿</option>
                            <option value="-5000-1000">-5000--1000亿</option>
                            <option value="-5000-">＜-5000亿</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 上涨率过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="upRatioFilter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">热度</option>
                            <option value="1-50">0-50</option>
                            <option value="50-150">50-150</option>
                            <option value="150-400">150-400</option>
                            <option value="400-2000">＞400</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 涨停率过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="limitUpRatioFilter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">涨停率</option>
                            <option value="0.01-5">0-5%</option>
                            <option value="5-10">5-10%</option>
                            <option value="10-20">10-20%</option>
                            <option value="20+">20%+</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 新增：排名变化过滤 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="rankChangeFilter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="">热涨变化</option>
                            <option value="1-1000">上升1-1000</option>
<!--                            <option value="11-50">上升11-50</option>-->
<!--                            <option value="51-100">上升51-100</option>-->
<!--                            <option value="101+">上升101+</option>-->
                            <option value="-1000-0">下降1-1000</option>
<!--                            <option value="-50-10">下降11-50</option>-->
<!--                            <option value="-100-50">下降51-100</option>-->
<!--                            <option value="-100-">下降100+</option>-->
                            <option value="0">不变</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 趋势过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="trendFilter" class="block w-full px-3 py-1 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="all">所有趋势</option>
                            <option value="上升">上升</option>
                            <option value="下降">下降</option>
                            <option value="反转">反转</option>
                            <option value="平稳">平稳</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                        <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                    </span>
                    </div>
                </div>

                <!-- 成员数过滤 - 选项已缩短 -->
                <div class="flex-1 min-w-[80px]">
                    <div class="relative">
                        <select id="memberCountFilter" class="block w-full px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary appearance-none bg-white compact-filter">
                            <option value="" selected>成员数</option>
                            <option value="0-0">无成员</option>
                            <option value="1-100">1-100</option>
                            <option value="101-300">101-300</option>
                            <option value="301-500">301-500</option>
                            <option value="501-1000">501-1000</option>
                            <option value="1001+">1001+</option>
                        </select>
                        <span class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                            <i class="fa fa-chevron-down text-gray-400 text-xs"></i>
                        </span>
                    </div>
                </div>
            </div>
        </div>

        <div class="flex items-center px-4 py-1 text-lg font-bold">
            总数:<span id="totalCount" class=" text-gray-900">-</span> &nbsp;
            上涨:<span id="upCount" class=" text-red-500">-</span>&nbsp;
            下跌:<span id="downCount" class=" text-green-500">-</span>&nbsp;
            平盘:<span id="pinCount" class=" text-gray-700">-</span>&nbsp;
            涨停:<span id="limitUpCount" class=" text-red-600">-</span>&nbsp;
            跌停:<span id="limitDownCount" class=" text-green-500">-</span>&nbsp;
            总资金:<span id="todayAll" class="font-medium text-red-600">-</span>
            &nbsp;总主力:<span id="todayAllMain" class="font-medium text-red-600">-</span>
        </div>

        <div class="flex items-center px-4 py-1 text-lg font-bold">
            关注:<span id="flowGainian" class="font-medium text-red-600">-</span>
        </div>
    </header>


    <div class="overflow-x-auto">
        <table class="w-full divide-y divide-gray-200 table-fixed-layout">
            <thead class="bg-gray-50">
            <tr>
                <th class="px-2 py-2 text-xs font-medium text-gray-500 w-16" style="width: 28px;" >
                    <input type="checkbox" id="select-all" class="select-all">
                </th>
                <th scope="col"  class="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider sortable-header" data-sort="marketValue" style="width: 90px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                    市值(亿)
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col"  class="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider sortable-header" data-sort="changePercent" style="width: 65px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                    涨幅
                    <i class="fa fa-sort sort-icon"></i>
                </th>

                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider sortable-header" data-sort="gainianName" style="width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                    概念名称
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 60px;" data-sort="day1">
                    1天
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day2">
                    2天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day2now">
                    2天前
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day3">
                    3天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day3now">
                    3天前
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day4">
                    4天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day5">
                    5天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day5now">
                    5天前
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day6">
                    6天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day6now">
                    6天前
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day7">
                    7天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="day7now">
                    7天前
                    <i class="fa fa-sort sort-icon"></i>
                </th>

                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 65px;" data-sort="day10">
                    10天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 65px;" data-sort="day20">
                    20天总
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="sunstocks">
                    成员数
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="sunstocksup">
                    上涨数
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 70px;" data-sort="sunstocksupratio">
                    上涨率
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 50px;" data-sort="sunstockslimit">
                    涨停
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 60px;" data-sort="sunstockslimitratio">
                    涨停率
                    <i class="fa fa-sort sort-icon"></i>
                </th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 50px;"  data-sort="rankPosition">新 <i class="fa fa-sort sort-icon"></i></th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 50px;"  data-sort="oldRankPosition">旧 <i class="fa fa-sort sort-icon"></i></th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 50px;"  data-sort="rankChange">热涨 <i class="fa fa-sort sort-icon"></i></th>
                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sortable-header" style="width: 60px;" data-sort="trend">
                    趋势
                    <i class="fa fa-sort sort-icon"></i>
                </th>
            </tr>
            </thead>
            <tbody id="summaryTableBody" class="bg-white divide-y divide-gray-200">
            <!-- 表格内容将通过JavaScript动态填充 -->
            <tr class="text-center">
                <td colspan="27" class="px-6 py-12 text-gray-500">
                    <div class="flex flex-col items-center">
                        <i class="fa fa-spinner fa-spin text-3xl mb-3 text-primary"></i>
                        <p>正在加载数据...</p>
                    </div>
                </td>
            </tr>
            </tbody>
        </table>
        <div class="table-stats flex justify-between items-center">
            <div>
                显示 <span id="currentDisplayCount">0</span> 条，共 <span id="totalRecordCount">0</span> 条记录
            </div>
            <div>
                <i class="fa fa-info-circle mr-1"></i>
                <span id="filterStatus">未应用过滤</span>
            </div>
        </div>
    </div>

    <div id="emptyState" class="hidden text-center py-12">
        <i class="fa fa-info-circle text-4xl text-gray-400 mb-4"></i>
        <h3 class="text-xl font-medium text-gray-900 mb-2">暂无数据</h3>
        <p class="text-gray-500 max-w-md mx-auto">没有找到符合条件的概念数据，请确保数据库中有相关记录。</p>
    </div>
</div>

<div class="bg-white rounded-xl p-6 table-shadow hover-scale">
    <h2 class="text-xl font-semibold text-neutral-dark mb-6">数据说明</h2>
    <div class="grid md:grid-cols-2 gap-6">
        <div class="bg-blue-50 p-4 rounded-lg">
            <h3 class="font-medium text-primary mb-2 flex items-center">
                <i class="fa fa-lightbulb-o mr-2"></i>数据含义
            </h3>
            <ul class="list-disc list-inside text-gray-700 space-y-1">
                <li>各时间段数据为对应天数内的资金流向总和</li>
                <li>资金流向单位为元，保留两位小数</li>
                <li>数据按概念代码进行分组统计</li>
                <li>点击列标题可进行排序</li>
            </ul>
        </div>
        <div class="bg-green-50 p-4 rounded-lg">
            <h3 class="font-medium text-green-700 mb-2 flex items-center">
                <i class="fa fa-bar-chart mr-2"></i>数据分析
            </h3>
            <ul class="list-disc list-inside text-gray-700 space-y-1">
                <li>对比不同时间段数据，可分析资金流向趋势</li>
                <li>红色箭头表示资金流入减少趋势</li>
                <li>绿色箭头表示资金流入增加趋势</li>
                <li>支持按各天数列进行升序/降序排序</li>
            </ul>
        </div>
    </div>
</div>
</div>

<footer class="bg-neutral-dark text-white py-8 mt-12">
    <div class="container mx-auto px-4">
        <div class="flex flex-col md:flex-row justify-between items-center">
            <div class="mb-4 md:mb-0">
                <h3 class="text-xl font-semibold mb-2">概念资金流向分析系统</h3>
                <p class="text-gray-400 text-sm">提供专业的股票概念数据分析服务</p>
            </div>
            <div class="flex space-x-6">
                <a href="#" class="text-gray-400 hover:text-white transition-colors">
                    <i class="fa fa-question-circle"></i> 帮助中心
                </a>
                <a href="#" class="text-gray-400 hover:text-white transition-colors">
                    <i class="fa fa-file-text-o"></i> 使用文档
                </a>
                <a href="#" class="text-gray-400 hover:text-white transition-colors">
                    <i class="fa fa-envelope-o"></i> 联系我们
                </a>
            </div>
        </div>
        <div class="border-t border-gray-700 mt-6 pt-6 text-center text-gray-400 text-sm">
            © 2025 概念资金流向分析系统. 保留所有权利.
        </div>
    </div>
</footer>
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
<script>
    // 全局变量
    let currentData = [];
    let currentSortField = null;
    let currentSortDirection = 'asc';
    let allstocks = 0;
    let todayAll = 0;
    let todayAllMain = 0;
    let stocksUP = 0;
    let stocksDown = 0;
    let stocksPin = 0;
    let stocksLimit = 0;
    let stocksDownLimit = 0;
    let flowGainian = "";
    let isFiltered = false;
    let createdAt = '';
    let savedFiltersVisible = false;
    let currentFilterId = null;

    $(document).ready(function() {
        // 为表格行绑定点击事件
        $('table').on('click', 'tr', function(e) {
            if($(e.target).is('input[type="checkbox"]')) return;
            var $checkbox = $(this).find('.row-checkbox');
            $checkbox.prop('checked', !$checkbox.prop('checked'));
            $(this).toggleClass('active', $checkbox.prop('checked'));
        });
        loadSavedFilters();
    });

    document.addEventListener('DOMContentLoaded', function() {
        fetchData();
        document.getElementById('searchBtn').addEventListener('click', performSearch);
        document.getElementById('nameSearch').addEventListener('input', function() {
            filterExistingData();
        });
        document.getElementById('startDate').addEventListener('change', function() {
            performSearch();
        });

        document.querySelectorAll('.sortable-header').forEach(header => {
            header.addEventListener('click', function() {
                const sortField = this.getAttribute('data-sort');
                handleSort(sortField);
            });
        });

        const today = new Date();
        document.getElementById('startDate').valueAsDate = today;

        document.getElementById('select-all').addEventListener('click', setupCheckboxHandler);

        // 添加所有过滤条件的事件监听，包括新增的排名变化过滤
        document.getElementById('trendFilter').addEventListener('input', filterExistingData);
        document.getElementById('memberCountFilter').addEventListener('change', filterExistingData);
        document.getElementById('changePercentFilter').addEventListener('change', filterExistingData);
        document.getElementById('day1Filter').addEventListener('change', filterExistingData);
        document.getElementById('day10Filter').addEventListener('change', filterExistingData);
        document.getElementById('day20Filter').addEventListener('change', filterExistingData);
        document.getElementById('upRatioFilter').addEventListener('change', filterExistingData);
        document.getElementById('limitUpRatioFilter').addEventListener('change', filterExistingData);
        document.getElementById('rankChangeFilter').addEventListener('change', filterExistingData); // 新增

        document.getElementById('loadFilterSelect').addEventListener('change', function() {
            const selectedValue = this.value;
            if (!selectedValue) {
                clearActiveFilters();
                currentFilterId = null;
                return;
            }

            try {
                currentFilterId = selectedValue;
                const selectedOption = this.options[this.selectedIndex];

                if (!selectedOption.dataset.conditions) {
                    console.error('未找到过滤条件数据');
                    return;
                }

                let conditions;
                conditions = JSON.parse(selectedOption.dataset.conditions);
                conditions = JSON.parse(conditions);

                const filterName = selectedOption.dataset.name || '未知条件';

                const nameSearch = conditions['nameSearch'] ?? '';
                const trendFilter = conditions['trendFilter'] ?? '';
                const memberCountFilter = conditions['memberCountFilter'] ?? '';
                const changePercentFilter = conditions['changePercentFilter'] ?? '';
                const day1Filter = conditions['day1Filter'] ?? '';
                const day10Value = conditions['day10Filter'] ?? '';
                const day20Value = conditions['day20Filter'] ?? '';
                const upRatioFilter = conditions['upRatioFilter'] ?? '';
                const limitUpRatioFilter = conditions['limitUpRatioFilter'] ?? '';
                const rankChangeFilter = conditions['rankChangeFilter'] ?? ''; // 新增

                performSearch();

                document.getElementById('nameSearch').value = nameSearch || '';
                document.getElementById('trendFilter').value = trendFilter || 'all';
                document.getElementById('memberCountFilter').value = memberCountFilter || '';
                document.getElementById('changePercentFilter').value = changePercentFilter || '';
                document.getElementById('day1Filter').value = day1Filter || '';
                document.getElementById('day10Filter').value = day10Value;
                document.getElementById('day20Filter').value = day20Value;
                document.getElementById('upRatioFilter').value = upRatioFilter || '';
                document.getElementById('limitUpRatioFilter').value = limitUpRatioFilter || '';
                document.getElementById('rankChangeFilter').value = rankChangeFilter || ''; // 新增

                addActiveFilterTag(filterName, selectedValue);

            } catch (error) {
                console.error('加载过滤条件失败:', error);
                alert('加载过滤条件时发生错误，请重试');
            }
        });

        loadSavedFilters();
        filterExistingData();
    });

    function showSaveFilterDialog() {
        document.getElementById('saveFilterDialog').classList.remove('hidden');
        document.getElementById('filterName').focus();
    }

    function openIwencaizhishu() {
        const baseUrl = 'https://www.iwencai.com/unifiedwap/result?w=%E6%89%80%E6%9C%89%E6%8C%87%E6%95%B0%E6%9D%BF%E5%9D%97,%E8%B5%84%E9%87%91,%E5%B8%82%E5%80%BC,%E6%B6%A8%E5%B9%85,%E6%9D%BF%E5%9D%97%E7%83%AD%E5%BA%A6%E6%8E%92%E5%90%8D,%E6%98%A8%E5%A4%A9%E6%9D%BF%E5%9D%97%E7%83%AD%E5%BA%A6%E6%8E%92%E5%90%8D&querytype=zhishu';
        window.open(baseUrl, '_blank');
    }

    function hideSaveFilterDialog() {
        document.getElementById('saveFilterDialog').classList.add('hidden');
        document.getElementById('filterName').value = '';
        document.getElementById('filterDescription').value = '';
    }

    function saveCurrentFilter() {
        const filterName = document.getElementById('filterName').value.trim();
        const filterDescription = document.getElementById('filterDescription').value.trim();

        if (!filterName) {
            alert('请输入条件名称');
            return;
        }

        // 收集当前过滤条件，包括新增的排名变化过滤
        const filterData = {
            name: filterName,
            description: filterDescription,
            conditions: {
                nameSearch: document.getElementById('nameSearch').value.trim(),
                startDate: document.getElementById('startDate').value,
                trendFilter: document.getElementById('trendFilter').value,
                memberCountFilter: document.getElementById('memberCountFilter').value,
                changePercentFilter: document.getElementById('changePercentFilter').value,
                day1Filter: document.getElementById('day1Filter').value,
                day10Filter: document.getElementById('day10Filter').value,
                day20Filter: document.getElementById('day20Filter').value,
                upRatioFilter: document.getElementById('upRatioFilter').value,
                limitUpRatioFilter: document.getElementById('limitUpRatioFilter').value,
                rankChangeFilter: document.getElementById('rankChangeFilter').value // 新增
            },
            createdAt: new Date().toISOString()
        };

        fetch('/api/filters', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(filterData)
        })
            .then(response => {
                if (!response.ok) {
                    throw new Error('保存过滤条件失败');
                }
                return response.json();
            })
            .then(data => {
                alert('过滤条件保存成功');
                hideSaveFilterDialog();
                loadSavedFilters();
            })
            .catch(error => {
                console.error('保存过滤条件失败:', error);
                alert('保存过滤条件失败: ' + error.message);
            });
        loadSavedFilters();
    }

    const formatTimeMD = (timeStr) => {
        if (!timeStr) return '-';
        const date = new Date(timeStr);
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        return `${month}-${day}`;
    };

    function loadSavedFilters() {
        const filterSelect = document.getElementById('loadFilterSelect');
        const filtersList = document.getElementById('savedFiltersList');

        fetch('/api/filters')
            .then(response => {
                if (!response.ok) {
                    throw new Error('获取过滤条件失败');
                }
                return response.json();
            })
            .then(filters => {
                while (filterSelect.options.length > 1) {
                    filterSelect.remove(1);
                }

                filtersList.innerHTML = '';

                if (filters.length === 0) {
                    const noFilterOption = document.createElement('option');
                    noFilterOption.value = "";
                    noFilterOption.disabled = true;
                    noFilterOption.textContent = "暂无保存的条件";
                    filterSelect.appendChild(noFilterOption);
                    filtersList.innerHTML = '<div class="text-center text-gray-500 py-4">暂无保存的过滤条件</div>';
                    return;
                }

                filters.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

                filters.forEach(filter => {
                    const option = document.createElement('option');
                    option.value = filter.id;
                    const formattedDate = formatTimeMD(filter.createdAt);
                    option.textContent = `${filter.name}(${formattedDate})`;
                    option.dataset.conditions = JSON.stringify(filter.conditions);
                    option.dataset.name = filter.name;
                    filterSelect.appendChild(option);

                    const filterItem = document.createElement('div');
                    filterItem.className = 'filter-item';

                    const formattedTime = new Date(filter.createdAt).toLocaleString();
                    filterItem.innerHTML = `
                        <div class="flex-1 min-w-0">
                            <div class="font-medium text-gray-900 truncate">${filter.name}</div>
                            <div class="text-xs text-gray-500">${formattedTime} ${filter.description ? '- ' + filter.description : ''}</div>
                        </div>
                        <div class="filter-actions">
                            <button class="filter-management-btn text-blue-600 hover:text-blue-800" onclick="applyFilter('${filter.id}')">
                                <i class="fa fa-check"></i> 应用
                            </button>
                            <button class="filter-management-btn text-red-600 hover:text-red-800" onclick="deleteFilter('${filter.id}')">
                                <i class="fa fa-trash"></i> 删除
                            </button>
                        </div>
                    `;
                    filtersList.appendChild(filterItem);
                });
            })
            .catch(error => {
                console.error('获取过滤条件失败:', error);
                const errorOption = document.createElement('option');
                errorOption.value = "";
                errorOption.disabled = true;
                errorOption.textContent = "加载条件失败";
                filterSelect.appendChild(errorOption);
                filtersList.innerHTML = '<div class="text-center text-red-500 py-4">加载条件失败</div>';
            });
    }

    function toggleSavedFilters() {
        const container = document.getElementById('savedFiltersContainer');
        savedFiltersVisible = !savedFiltersVisible;

        if (savedFiltersVisible) {
            container.classList.remove('hidden');
        } else {
            container.classList.add('hidden');
        }
    }

    function applyFilter(filterId) {
        fetch(`/api/filters/${filterId}`)
            .then(response => {
                if (!response.ok) {
                    throw new Error('获取过滤条件详情失败');
                }
                return response.json();
            })
            .then(filter => {
                const conditions = filter.conditions;

                document.getElementById('nameSearch').value = conditions.nameSearch || '';
                document.getElementById('startDate').value = conditions.startDate || '';
                document.getElementById('trendFilter').value = conditions.trendFilter || 'all';
                document.getElementById('memberCountFilter').value = conditions.memberCountFilter || '';
                document.getElementById('changePercentFilter').value = conditions.changePercentFilter || '';
                document.getElementById('day1Filter').value = conditions.day1Filter || '';
                document.getElementById('day10Filter').value = conditions.day10Filter || '';
                document.getElementById('day20Filter').value = conditions.day20Filter || '';
                document.getElementById('upRatioFilter').value = conditions.upRatioFilter || '';
                document.getElementById('limitUpRatioFilter').value = conditions.limitUpRatioFilter || '';
                document.getElementById('rankChangeFilter').value = conditions.rankChangeFilter || ''; // 新增

                currentFilterId = filterId;
                addActiveFilterTag(filter.name, filterId);
                performSearch();
                toggleSavedFilters();
            })
            .catch(error => {
                console.error('应用过滤条件失败:', error);
                alert('应用过滤条件失败: ' + error.message);
            });
    }

    function addActiveFilterTag(filterName, filterId) {
        clearActiveFilters();
    }

    function clearActiveFilters() {
    }

    function removeActiveFilter(filterId) {
        const tag = document.querySelector(`.active-filter-tag[data-filter-id="${filterId}"]`);
        if (tag) {
            tag.remove();
        }

        document.getElementById('loadFilterSelect').value = '';
        currentFilterId = null;
        resetAllFilters();
    }

    function deleteFilter(filterId) {
        if (!confirm('确定要删除这个过滤条件吗？')) {
            return;
        }

        fetch(`/api/filters/${filterId}`, {
            method: 'DELETE'
        })
            .then(response => {
                if (!response.ok) {
                    throw new Error('删除过滤条件失败');
                }
                return response.json();
            })
            .then(data => {
                alert('过滤条件已删除');
                loadSavedFilters();

                if (currentFilterId === filterId) {
                    clearActiveFilters();
                    currentFilterId = null;
                }
            })
            .catch(error => {
                console.error('删除过滤条件失败:', error);
                alert('删除过滤条件失败: ' + error.message);
            });
        loadSavedFilters();
    }

    function deleteSelectedFilter() {
        const selectedValue = document.getElementById('loadFilterSelect').value;

        if (!selectedValue) {
            alert('请先选择要删除的过滤条件');
            return;
        }

        if (confirm('确定要删除这个过滤条件吗？此操作不可恢复。')) {
            fetch(`/api/filters/${selectedValue}`, {
                method: 'DELETE'
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('删除过滤条件失败');
                    }
                    return response.json();
                })
                .then(data => {
                    alert('过滤条件已成功删除');
                    document.getElementById('loadFilterSelect').value = '';
                    clearActiveFilters();
                    currentFilterId = null;
                    loadSavedFilters();
                })
                .catch(error => {
                    console.error('删除过滤条件失败:', error);
                    alert('删除过滤条件失败: ' + error.message);
                });
        }
    }

    function resetAllFilters() {
        document.getElementById('nameSearch').value = '';
        document.getElementById('trendFilter').value = 'all';
        document.getElementById('memberCountFilter').value = '';
        document.getElementById('changePercentFilter').value = '';
        document.getElementById('day1Filter').value = '';
        document.getElementById('day10Filter').value = '';
        document.getElementById('day20Filter').value = '';
        document.getElementById('upRatioFilter').value = '';
        document.getElementById('limitUpRatioFilter').value = '';
        document.getElementById('rankChangeFilter').value = ''; // 新增

        isFiltered = false;
        updateFilterStatus();

        currentSortField = null;
        currentSortDirection = 'asc';
        document.querySelectorAll('.sort-icon').forEach(icon => {
            icon.className = 'fa fa-sort sort-icon';
        });

        clearActiveFilters();
        document.getElementById('loadFilterSelect').value = '';
        currentFilterId = null;

        filterExistingData();
    }

    function filterExistingData() {
        const tableBody = document.getElementById('summaryTableBody');
        let nameSearch = document.getElementById('nameSearch').value.trim().toLowerCase();
        if (nameSearch === "=") {
            nameSearch = flowGainian;
        }

        // 获取所有过滤条件，包括新增的排名变化过滤
        const trendFilter = document.getElementById('trendFilter').value;
        const memberCountFilter = document.getElementById('memberCountFilter').value.trim();
        const changePercentFilter = document.getElementById('changePercentFilter').value.trim();
        const day1Filter = document.getElementById('day1Filter').value.trim();
        const day10Filter = document.getElementById('day10Filter').value.trim();
        const day20Filter = document.getElementById('day20Filter').value.trim();
        const upRatioFilter = document.getElementById('upRatioFilter').value.trim();
        const limitUpRatioFilter = document.getElementById('limitUpRatioFilter').value.trim();
        const rankChangeFilter = document.getElementById('rankChangeFilter').value.trim(); // 新增

        // 检查是否有任何过滤条件被应用
        isFiltered = nameSearch !== '' || trendFilter !== 'all' || memberCountFilter !== '' ||
            changePercentFilter !== '' || day1Filter !== '' || day10Filter !== '' ||
            day20Filter !== '' || upRatioFilter !== '' || limitUpRatioFilter !== '' ||
            rankChangeFilter !== ''; // 新增

        updateFilterStatus();

        let filteredData = [...currentData];

        // 名称模糊过滤
        if (nameSearch) {
            const searchTerms = nameSearch.toLowerCase().split(',').map(term => term.trim());
            filteredData = filteredData.filter(item => {
                const gainianName = item.gainianName.toLowerCase();
                const gainianNamepy = item.gainianNamepy ? item.gainianNamepy.toLowerCase() : '';
                const gaiFlag = gainianName.includes(nameSearch.toLowerCase()) ||
                    searchTerms.some(term => term && gainianName.includes(term));

                const gaiPyFlag = gainianNamepy.includes(nameSearch.toLowerCase()) ||
                    searchTerms.some(term => term && gainianNamepy.includes(term));
                return gaiFlag || gaiPyFlag;
            });
        }

        // 趋势过滤
        if (trendFilter && trendFilter !== 'all') {
            filteredData = filteredData.filter(item => {
                const day1 = Number(item.day1 || 0) / 10000 / 10000;
                const day2 = Number(item.day2now || 0) / 10000 / 10000;
                const day3 = Number(item.day3now || 0) / 10000 / 10000;

                const currentRank = Number(item.rankPosition);
                const oldRank = Number(item.oldRankPosition);
                const change = oldRank - currentRank;

                let trendText;
                if (day1 > day2 && day2 > day3) {
                    trendText = '上升';
                } else if (day1 < day2 && day2 < day3) {
                    trendText = '下降';
                } else {
                    trendText = day1 > 0 ? '反转' : '平稳';
                }

                return trendText === trendFilter;
            });
        }

        // 成员数过滤
        if (memberCountFilter) {
            filteredData = filterByRange(filteredData, 'sunstocks', memberCountFilter);
        }

        // 涨幅过滤
        if (changePercentFilter) {
            filteredData = filterByRange(filteredData, 'changePercent', changePercentFilter, true);
        }

        // 1天资金过滤
        if (day1Filter) {
            filteredData = filteredData.filter(item => {
                const value = Number(item.day1 || 0) / 10000 / 10000;
                return isInRange(value, day1Filter);
            });
        }

        // 10天资金过滤
        if (day10Filter) {
            filteredData = filteredData.filter(item => {
                const value = Number(item.day10 || 0) / 10000 / 10000;
                return isInRange(value, day10Filter);
            });
        }

        // 20天资金过滤
        if (day20Filter) {
            filteredData = filteredData.filter(item => {
                const value = Number(item.day20 || 0) / 10000 / 10000;
                return isInRange(value, day20Filter);
            });
        }

        // 上涨率过滤
        if (upRatioFilter) {
            filteredData = filteredData.filter(item => {
                const value = Number(item.rankPosition || 0);
                return isInRange(value, upRatioFilter);
            });
        }

        // 涨停率过滤
        if (limitUpRatioFilter) {
            filteredData = filterByRange(filteredData, 'sunstockslimitratio', limitUpRatioFilter, true);
        }

        // 新增：排名变化过滤
        if (rankChangeFilter) {
            filteredData = filteredData.filter(item => {
                // 计算排名变化值
                const currentRank = Number(item.rankPosition || 0);
                const oldRank = Number(item.oldRankPosition || 0);
                const change = oldRank - currentRank;

                // 特殊处理"不变"的情况
                if (rankChangeFilter === "0") {
                    return change === 0;
                }

                return isInRange(change, rankChangeFilter);
            });
        }

        updateRecordCount(filteredData.length, currentData.length);

        if (filteredData.length === 0 && currentData.length === 0) {
            tableBody.innerHTML = `
            <tr class="text-center">
                <td colspan="27" class="px-6 py-12 text-gray-500">
                    <div class="flex flex-col items-center">
                        <i class="fa fa-search text-3xl mb-3 text-gray-400"></i>
                        <p>没有找到匹配的数据</p>
                    </div>
                </td>
            </tr>
        `;
            return;
        }

        if (currentSortField) {
            const sortedData = sortData([...filteredData], currentSortField, currentSortDirection);
            renderTableData(sortedData);
        } else {
            renderTableData(filteredData);
        }
    }

    function updateFilterStatus() {
        const filterStatusEl = document.getElementById('filterStatus');
        if (isFiltered) {
            filterStatusEl.innerHTML = '<i class="fa fa-filter text-primary mr-1"></i>已应用过滤条件';
            filterStatusEl.className = 'text-primary';
        } else {
            filterStatusEl.textContent = '未应用过滤';
            filterStatusEl.className = '';
        }
    }

    function updateRecordCount(displayCount, totalCount) {
        document.getElementById('currentDisplayCount').textContent = displayCount;
        document.getElementById('totalRecordCount').textContent = totalCount;
    }

    function filterByRange(data, field, rangeStr, isPercentage = false) {
        return data.filter(item => {
            let value;

            if (isPercentage) {
                if (typeof item[field] === 'string') {
                    value = parseFloat(item[field].replace('%', ''));
                } else {
                    value = Number(item[field] || 0);
                }
            } else {
                value = Number(item[field] || 0);
            }

            return isInRange(value, rangeStr);
        });
    }

    function isInRange(value, rangeStr) {
        let min, max;

        if (rangeStr.endsWith('+')) {
            min = parseFloat(rangeStr.replace('+', ''));
            max = Infinity;
            return value >= min;
        }

        if (rangeStr.endsWith('-')) {
            max = parseFloat(rangeStr.replace('-', ''));
            min = -Infinity;
            return value <= max;
        }

        const [minStr, maxStr] = rangeStr.split('-');
        min = parseFloat(minStr);
        max = parseFloat(maxStr);

        if (minStr.startsWith('-') && maxStr.startsWith('-') && min < max) {
            [min, max] = [max, min];
        }

        return value >= min && value <= max;
    }

    function setupCheckboxHandler() {
        const selectAllCheckbox = document.getElementById('select-all');
        const rowCheckboxes = document.querySelectorAll('input[name="select-stockCode"]');

        selectAllCheckbox.addEventListener('change', function() {
            rowCheckboxes.forEach(checkbox => {
                checkbox.checked = this.checked;
            });
        });

        rowCheckboxes.forEach(checkbox => {
            checkbox.addEventListener('change', function() {
                const allChecked = Array.from(rowCheckboxes).every(cb => cb.checked);
                selectAllCheckbox.checked = allChecked;
            });
        });
    }

    function performSearch() {
        document.getElementById('trendFilter').value = 'all';
        document.getElementById('memberCountFilter').value = '';
        document.getElementById('changePercentFilter').value = '';
        document.getElementById('day1Filter').value = '';
        document.getElementById('day10Filter').value = '';
        document.getElementById('day20Filter').value = '';
        document.getElementById('upRatioFilter').value = '';
        document.getElementById('limitUpRatioFilter').value = '';
        document.getElementById('rankChangeFilter').value = ''; // 新增

        isFiltered = false;
        updateFilterStatus();

        const tableBody = document.getElementById('summaryTableBody');
        const nameSearch = document.getElementById('nameSearch').value.trim().toLowerCase();
        const startDate = document.getElementById('startDate').value;

        tableBody.innerHTML = `
            <tr class="text-center">
                <td colspan="27" class="px-6 py-12 text-gray-500">
                    <div class="flex flex-col items-center">
                        <i class="fa fa-spinner fa-spin text-3xl mb-3 text-primary"></i>
                        <p>正在查询数据...</p>
                    </div>
                </td>
            </tr>
        `;

        const params = new URLSearchParams();
        if (nameSearch) params.append('nameSearch', nameSearch);
        if (startDate) params.append('startDate', startDate);

        fetch(`/gainian/summary?${params.toString()}`)
            .then(response => response.json())
            .then(data => {
                currentData = data.result;

                allstocks = data.allstocks ;
                todayAll = data.todayAll ;
                todayAllMain = data.todayAllMain ;
                createdAt = data.createdAt ;
                stocksUP =data.stocksUP;
                stocksDown = data.stocksDown;
                stocksPin = data.stocksPin;
                stocksLimit = data.stocksLimit;
                stocksDownLimit = data.stocksDownLimit;
                flowGainian = data.flowGainian;

                updateLastUpdateTime();
                updateStats();

                if (data.result==null || data.result.length==0){
                    updateRecordCount(0, 0);
                } else {
                    updateRecordCount(data.result.length, data.result.length);
                }

                if (data.result==null || data.result.length === 0) {
                    tableBody.innerHTML = `
                        <tr class="text-center">
                            <td colspan="27" class="px-6 py-12 text-gray-500">
                                <div class="flex flex-col items-center">
                                    <i class="fa fa-search text-3xl mb-3 text-gray-400"></i>
                                    <p>没有找到匹配的数据</p>
                                </div>
                            </td>
                        </tr>
                    `;
                    return;
                }

                if (currentSortField) {
                    sortAndRenderData();
                } else {
                    renderTableData(data.result);
                }
                filterExistingData();
            })
            .catch(error => {
                console.error('查询失败:', error);
                tableBody.innerHTML = `
                    <tr class="text-center">
                        <td colspan="27" class="px-6 py-12 text-red-500">
                            <div class="flex flex-col items-center">
                                <i class="fa fa-exclamation-triangle text-3xl mb-3"></i>
                                <p>加载数据失败，请稍后重试</p>
                            </div>
                        </td>
                    </tr>
                `;
                updateRecordCount(0, 0);
            });
    }

    function openSelectedGainianCodesJQ() {
        let selectedCodes = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get();

        if (selectedCodes.length === 0) {
            alert('请先选择板块');
            return;
        }

        selectedCodes.forEach(code => {
            const targetUrl = `/gainian/summarycode?code=${encodeURIComponent(code)}`;
            window.open(targetUrl, '_blank');
        });
    }

    function openSelectedStockCodes(selectedCode) {
        if (selectedCode === '' || selectedCode === null) {
            alert('请先选择板块');
            return;
        }

        const targetUrl = `/gainian/summarycode?code=${encodeURIComponent(selectedCode)}`;
        window.open(targetUrl, '_blank');
    }


    function addupdateFocusGainian() {
        var focusGainian = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');

        if (!focusGainian || focusGainian.trim() === '') {
            alert('没有选择代码');
            return;
        }

        focusGainian=(focusGainian ? focusGainian.split('\n').join(',') : '');
        $.ajax({
            url: '/sysinfo/appendBy',
            method: 'GET',
            data: {
                focusGainian: focusGainian
            },
            success: function (response) {
                alert('关注成功');
            },
            error: function (xhr, status, error) {
                console.error('概念查询失败:', error);
                $('#loadingIndicator').removeClass('active');
            }
        });
    }

    function removeupdateFocusGainian() {
        var focusGainian = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');

        if (!focusGainian || focusGainian.trim() === '') {
            alert('没有选择代码');
            return;
        }

        focusGainian=(focusGainian ? focusGainian.split('\n').join(',') : '');
        $.ajax({
            url: '/sysinfo/removeBy',
            method: 'GET',
            data: {
                focusGainian: focusGainian
            },
            success: function (response) {
                alert('取消关注成功');
            },
            error: function (xhr, status, error) {
                console.error('概念查询失败:', error);
                $('#loadingIndicator').removeClass('active');
            }
        });
    }

    function updateStats() {
        const totalEl = document.getElementById('totalCount');
        const upEl = document.getElementById('upCount');
        const downEl = document.getElementById('downCount');
        const pinEl = document.getElementById('pinCount');
        const limitUpEl = document.getElementById('limitUpCount');
        const limitDownEl = document.getElementById('limitDownCount');
        const flowGainianEL = document.getElementById('flowGainian');

        totalEl.textContent = allstocks !== undefined ? allstocks : '-';
        upEl.textContent = stocksUP !== undefined ? stocksUP : '-';
        downEl.textContent = stocksDown !== undefined ? stocksDown : '-';
        pinEl.textContent = stocksPin !== undefined ? stocksPin : '-';
        limitUpEl.textContent = stocksLimit !== undefined ? stocksLimit : '-';
        limitDownEl.textContent = stocksDownLimit !== undefined ? stocksDownLimit : '-';
        flowGainianEL.textContent = flowGainian !== undefined ? flowGainian : '-';

        const todayAllEL = document.getElementById('todayAll');
        todayAllEL.innerHTML = todayAll !== undefined ? formatNumber(todayAll) : '-';

        const todayAllMainEL = document.getElementById('todayAllMain');
        todayAllMainEL.innerHTML = todayAllMain !== undefined ? formatNumber(todayAllMain) : '-';
    }

    function updateLastUpdateTime() {
        if (!createdAt) {
            document.getElementById('lastUpdateTime').textContent = '未获取到时间';
            return;
        }

        try {
            const formatTime = (dateT) => {
                if (!dateT) return '-';
                const date = new Date(dateT);
                if (isNaN(date.getTime())) {
                    return '无效时间';
                }

                return date.toLocaleString('zh-CN', {
                    year: 'numeric',
                    month: '2-digit',
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                    second: '2-digit'
                });
            };

            const timeElement = document.getElementById('lastUpdateTime');
            if (timeElement) {
                timeElement.textContent = formatTime(createdAt);
            } else {
                console.error('未找到lastUpdateTime元素');
            }
        } catch (error) {
            console.error('时间格式化出错:', error);
            document.getElementById('lastUpdateTime').textContent = '时间格式错误';
        }
    }

    function handleSort(sortField) {
        if (currentSortField === sortField) {
            currentSortDirection = currentSortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            currentSortField = sortField;
            currentSortDirection = ['gainianName', 'trend', 'gainianName'].includes(sortField) ? 'asc' : 'desc';
        }

        updateSortIcons(sortField, currentSortDirection);

        const nameSearch = document.getElementById('nameSearch').value.trim().toLowerCase();
        let dataToSort = [...currentData];

        if (nameSearch) {
            dataToSort = dataToSort.filter(item =>
                item.gainianName.toLowerCase().includes(nameSearch)
            );
        }

        filterExistingData();
    }

    function sortData(data, field, direction) {
        return [...data].sort((a, b) => {
            if (field === 'trend') {
                const trendA = getTrendValue(a);
                const trendB = getTrendValue(b);
                return direction === 'desc' ? trendB - trendA:trendA - trendB ;
            }

            if (field === 'rankChange') {
                const trendA = calculateRankChange(a.rankPosition,a.oldRankPosition);
                const trendB = calculateRankChange(b.rankPosition,b.oldRankPosition);
                return direction === 'asc' ? trendA.value - trendB.value : trendB.value - trendA.value;
            }

            if (field === 'rankPosition') {
                const nameA = a[field] ? a[field] : 1000;
                const nameB = b[field] ? b[field] : 1000;
                return direction === 'asc' ? nameA - nameB : nameB - nameA;
            }

            if (field === 'gainianName') {
                const nameA = a[field] ? a[field].toLowerCase() : '';
                const nameB = b[field] ? b[field].toLowerCase() : '';
                return direction === 'asc' ? nameA.localeCompare(nameB) : nameB.localeCompare(nameA);
            }

            if (field === 'gainianCode') {
                const nameA = a[field] ? a[field].toLowerCase() : '';
                const nameB = b[field] ? b[field].toLowerCase() : '';
                return direction === 'asc' ? nameA.localeCompare(nameB) : nameB.localeCompare(nameA);
            }

            const aValue = parseFloat(a[field]) || 0;
            const bValue = parseFloat(b[field]) || 0;
            return direction === 'asc' ? aValue - bValue : bValue - aValue;
        });
    }

    function getTrendValue(item) {
        const day1 = Number(item.day1 || 0) / 10000 / 10000;
        const day2 = Number(item.day2now || 0) / 10000 / 10000;
        const day3 = Number(item.day3now || 0) / 10000 / 10000;

        if (day1 > day2 && day2 > day3) {
            return 1;
        } else if (day1 < day2 && day2 < day3) {
            return 4;
        } else {
            if (day1>0){
                return 2;
            }else {
                return 3;
            }
        }
    }

    function updateSortIcons(activeField, direction) {
        document.querySelectorAll('.sortable-header').forEach(header => {
            const icon = header.querySelector('.sort-icon');
            const field = header.getAttribute('data-sort');

            if (field === activeField) {
                icon.className = `fa ${direction === 'asc' ? 'fa-sort-up' : 'fa-sort-down'} sort-icon active`;
            } else {
                icon.className = 'fa fa-sort sort-icon';
            }
        });
    }

    function sortAndRenderData() {
        if (currentData.length === 0) return;

        const sortedData = sortData([...currentData], currentSortField, currentSortDirection);
        renderTableData(sortedData);
        updateRecordCount(sortedData.length, currentData.length);
    }

    function calculateRankChange(current, old) {
        const currentRank = Number(current);
        const oldRank = Number(old);

        if (isNaN(currentRank) || isNaN(oldRank) ||
            !isFinite(currentRank) || !isFinite(oldRank) ||
            currentRank <= 0 || oldRank <= 0) {
            return { class: 'text-gray-400', html: '-' };
        }
        const change = oldRank - currentRank;

        if (change < 0) {
            return {
                class: 'text-green-500 font-medium',
                value: change,
                html: `<i class="fa" aria-hidden="true"></i> ${Math.abs(change)}`
            };
        } else if (change > 0) {
            return {
                class: 'text-red-500 font-medium',
                value: change,
                html: `<i class="fa" aria-hidden="true"></i> ${change}`
            };
        } else {
            return {
                class: 'text-gray-500',
                value: change,
                html: `<i class="fa " aria-hidden="true"></i> 0`
            };
        }
    }

    const formatNumber = (num) => {
        if (num === null || num === undefined) return '0.00';

        const value = Number(num) / 10000 / 10000;
        const formattedValue = value.toLocaleString('zh-CN', {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2,
            useGrouping: false
        });

        const escapedValue = formattedValue
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');

        if (value > 0) {
            return `<span class="text-red-500">${escapedValue}</span>`;
        } else if (value < 0) {
            return `<span class="text-green-500">${escapedValue}</span>`;
        }
        return escapedValue;
    };

    function renderTableData(data) {
        const tableBody = document.getElementById('summaryTableBody');
        tableBody.innerHTML = '';

        data.forEach(item => {
            const row = document.createElement('tr');
            row.className = 'border-t border-gray-200 hover:bg-[#FFFF00] transition-colors';

            const formatDouble = (num) => {
                if (num === null || num === undefined || num === 0) return '0.00';

                const formattedValue = num.toFixed(2);
                const escapedValue = formattedValue
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;');

                if (num > 0) {
                    return `<span class="text-red-500">${escapedValue}</span>`;
                } else if (num < 0) {
                    return `<span class="text-green-500">${escapedValue}</span>`;
                }
                return escapedValue;
            };

            const getTrendIcon = () => {
                const day1 = Number(item.day1 || 0) / 10000 / 10000;
                const day2 = Number(item.day2now || 0) / 10000 / 10000;
                const day3 = Number(item.day3now || 0) / 10000 / 10000;

                if (day1 > day2 && day2 > day3) {
                    return '<i class="fa fa-arrow-up text-red-500 "></i> 上升';
                } else if (day1 < day2 && day2 < day3) {
                    return '<i class="fa fa-arrow-down text-green-500"></i> 下降';
                } else {
                    if (day1>0){
                        return '<i class="fa fa-arrow-up text-red-500 "></i> 反转';
                    }else {
                        return '<i class="fa fa-minus text-gray-500"></i> 平稳';
                    }
                }
            };

            const rankChange = calculateRankChange(item.rankPosition, item.oldRankPosition);

            row.innerHTML = `
                    <td class="px-4 py-3 font-medium"><input type="checkbox" class="row-checkbox" name="select-stockCode" value="${item.gainianName || ''}" data-id="${item.gainianName || ''}"></td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 sm:text-right">${formatNumbers(item.marketValue)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium ${formatNumberClass(item.changePercent)}">${formatNumbers(item.changePercent)}%</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                               ${flowGainian && flowGainian.includes(item.gainianName) ? 'background-color: #FFFF00;' : ''}" onclick="openSelectedStockCodes('${item.gainianName || ''}')">
                      ${item.gainianName}
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 font-medium">${formatNumber(item.day1)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day2)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900" style="background-color: #DFD3B9;">${formatNumber(item.day2now)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day3)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900" style="background-color: #DFD3B9;">${formatNumber(item.day3now)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day4)}</td>

                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day5)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900" style="background-color: #DFD3B9;">${formatNumber(item.day5now)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day6)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900" style="background-color: #DFD3B9;">${formatNumber(item.day6now)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day7)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900" style="background-color: #DFD3B9;">${formatNumber(item.day7now)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day10)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatNumber(item.day20)}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.sunstocks != null ? item.sunstocks : '-'}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 ${formatNumberClass(item.sunstocksup)}">${item.sunstocksup}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 ${formatNumberClass(item.sunstocksupratio)}">${formatDouble(item.sunstocksupratio)}%</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 ${formatNumberClass(item.sunstockslimit)}">${item.sunstockslimit}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 ${formatNumberClass(item.sunstockslimitratio)}">${formatDouble(item.sunstockslimitratio)}%</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 ">${item.rankPosition}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 ">${item.oldRankPosition}</td>
                    <td class="px-4 py-3 ${rankChange.class}">${rankChange.html}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${getTrendIcon()}</td>
                `;
            tableBody.appendChild(row);
        });
    }

    function formatNumberClass(number) {
        if (!number) return '';
        const num = new Number(number);
        if (num > 0) return 'text-red-500';
        if (num < 0) return 'text-green-500';
        return '';
    }

    function formatNumbers(number) {
        if (number === null || number === undefined || isNaN(number)) return '-';

        let num = typeof number === 'string' && number.includes('E')
            ? new Number(number)
            : Number(number);
        return num.toLocaleString('zh-CN', {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2,
            useGrouping: false
        });
    }

    function getSelectedStockCodesJQ() {
        let selectCode = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');
        copyToClipboard(selectCode);
    }

    function jumpToEastMoneySearch() {
        let selectCode = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');
        if (!selectCode || selectCode.trim() === '') {
            alert("未选择内容");
        }else{
            window.open("https://so.eastmoney.com/Web/s?keyword=" + selectCode, "_blank");
        }
    }

    function fetchData() {
        const tableBody = document.getElementById('summaryTableBody');
        const emptyState = document.getElementById('emptyState');

        tableBody.innerHTML = `
                <tr class="text-center">
                    <td colspan="27" class="px-6 py-12 text-gray-500">
                        <div class="flex flex-col items-center">
                            <i class="fa fa-spinner fa-spin text-3xl mb-3 text-primary"></i>
                            <p>正在加载数据...</p>
                        </div>
                    </td>
                </tr>
            `;
        emptyState.classList.add('hidden');

        const today = new Date();
        const startDate = today.toISOString().split('T')[0];
        const params = new URLSearchParams({ startDate });

        fetch(`/gainian/summary?${params.toString()}`)
            .then(response => response.json())
            .then(data => {
                if (data.result==null || data.result.length === 0) {
                    tableBody.innerHTML = '';
                    emptyState.classList.remove('hidden');
                    updateRecordCount(0, 0);
                    return;
                }
                emptyState.classList.add('hidden');
                currentData = data.result;
                allstocks = data.allstocks;
                todayAll = data.todayAll;
                todayAllMain = data.todayAllMain;
                createdAt = data.createdAt;
                stocksUP = data.stocksUP;
                stocksDown = data.stocksDown;
                stocksPin = data.stocksPin;
                stocksLimit = data.stocksLimit;
                stocksDownLimit = data.stocksDownLimit;
                flowGainian = data.flowGainian;

                updateLastUpdateTime();
                renderTableData(data.result);
                filterExistingData();
                updateStats();

                if (data.result==null || data.result.length==0){
                    updateRecordCount(0, 0);
                } else {
                    updateRecordCount(data.result.length, data.result.length);
                }
            })
            .catch(error => {
                console.error('Error fetching data:', error);
                tableBody.innerHTML = `
                        <tr class="text-center">
                            <td colspan="27" class="px-6 py-12 text-red-500">
                                <div class="flex flex-col items-center">
                                    <i class="fa fa-exclamation-triangle text-3xl mb-3"></i>
                                    <p>加载数据失败，请稍后重试</p>
                                </div>
                            </td>
                        </tr>
                    `;
                updateRecordCount(0, 0);
            });
    }

    function copyToClipboard(stockCodes) {
        event.stopPropagation();

        if (!stockCodes || stockCodes.trim() === '') {
            alert('没有概念可复制');
            return;
        }

        if (navigator.clipboard && window.isSecureContext) {
            navigator.clipboard.writeText(stockCodes).then(() => {
                showCopySuccessToast(stockCodes.split(',').length);
            }).catch(err => {
                console.error('复制失败:', err);
                fallbackCopy(stockCodes);
            });
        } else {
            fallbackCopy(stockCodes);
        }
    }

    function fallbackCopy(text) {
        const textArea = document.createElement('textarea');
        textArea.value = text;
        textArea.style.position = 'fixed';
        textArea.style.left = '-999999px';
        textArea.style.top = '-999999px';
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            document.execCommand('copy');
            showCopySuccessToast(text.split(',').length);
        } catch (err) {
            console.error('降级复制也失败了:', err);
            alert('复制失败，请手动复制：' + text);
        } finally {
            document.body.removeChild(textArea);
        }
    }

    function showCopySuccessToast(count) {
        const toast = document.createElement('div');
        toast.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #28a745;
                color: white;
                padding: 12px 20px;
                border-radius: 6px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                z-index: 9999;
                font-size: 12px;
                font-weight: 500;
                display: flex;
                align-items: center;
                gap: 8px;
                opacity: 0;
                transform: translateX(100%);
                transition: all 0.3s ease;
            `;

        toast.innerHTML = `
                <i class="fa fa-check-circle" aria-hidden="true"></i>
                已复制 ${count} 个概念
            `;

        document.body.appendChild(toast);

        setTimeout(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(0)';
        }, 100);

        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(100%)';
            setTimeout(() => {
                if (document.body.contains(toast)) {
                    document.body.removeChild(toast);
                }
            }, 300);
        }, 3000);
    }
</script>
</body>
</html>
